(deftemplate modeler-instance (slot instance) (slot from-rule-number))
(deftemplate modeler-instance-param (slot instance) (slot name) (multislot value))

(defrule binding-rule-1
    (declare (salience 102))
    (unbound-table-instance (table-id ?t0__) (has schema time-profile))
    (unbound-table-instance (table-id ?t0__) (has record-waiting-threads $?record-waiting-threads))
    (unbound-table-instance (table-id ?t0__) (has record-waiting-threads 1))
    (unbound-table-instance (table-id ?t0__) (has target-pid $?target))
    (unbound-table-instance (table-id ?t0__) (has high-frequency-sampling $?high-freq))
    (unbound-table-instance (table-id ?t0__) (has high-frequency-sampling 1))
    (unbound-table-instance (table-id ?t0__) (has needs-kernel-callstack $?needs-kernel-callstack))
    =>
    (bind ?instance__ (create-modeler-instance))
    (assert (modeler-instance (instance ?instance__) (from-rule-number 1)))
    (bind-output-table ?t0__)
    (bind-input-table time-sample (attribute sample-rate-micro-seconds 1000) (attribute all-thread-states YES) (attribute callstack (if (eq (nth$ 1 ?needs-kernel-callstack) 1) then (create$ user kernel) else (create$ user))) (attribute target $?target))
    (assert (modeler-instance-param (instance ?instance__) (name record-waiting-threads) (value ?record-waiting-threads)))
    (assert (modeler-instance-param (instance ?instance__) (name needs-kernel-callstack) (value ?needs-kernel-callstack)))
    (assert (modeler-instance-param (instance ?instance__) (name target) (value ?target)))
    (assert (modeler-instance-param (instance ?instance__) (name high-freq) (value ?high-freq)))
)
(defrule binding-rule-2
    (declare (salience 201))
    (unbound-table-instance (table-id ?t0__) (has schema time-profile))
    (unbound-table-instance (table-id ?t0__) (has record-waiting-threads $?record-waiting-threads))
    (unbound-table-instance (table-id ?t0__) (has record-waiting-threads 1))
    (unbound-table-instance (table-id ?t0__) (has target-pid $?target))
    (unbound-table-instance (table-id ?t0__) (has high-frequency-sampling $?high-freq))
    (unbound-table-instance (table-id ?t0__) (has high-frequency-sampling 1))
    (unbound-table-instance (table-id ?t0__) (has needs-kernel-callstack $?needs-kernel-callstack))
    (unbound-table-instance (table-id ?t1__&~?t0__) (has schema time-profile))
    (unbound-table-instance (table-id ?t1__) (has record-waiting-threads $?record-waiting-threads))
    (unbound-table-instance (table-id ?t1__) (has record-waiting-threads 0))
    (unbound-table-instance (table-id ?t1__) (has target-pid $?target))
    (unbound-table-instance (table-id ?t1__) (has high-frequency-sampling $?high-freq))
    (unbound-table-instance (table-id ?t1__) (has high-frequency-sampling 1))
    (unbound-table-instance (table-id ?t1__) (has needs-kernel-callstack $?needs-kernel-callstack))
    =>
    (bind ?instance__ (create-modeler-instance))
    (assert (modeler-instance (instance ?instance__) (from-rule-number 2)))
    (bind-output-table ?t0__)
    (bind-input-table time-sample (attribute sample-rate-micro-seconds 1000) (attribute all-thread-states YES) (attribute callstack (if (eq (nth$ 1 ?needs-kernel-callstack) 1) then (create$ user kernel) else (create$ user))) (attribute target $?target))
    (assert (modeler-instance-param (instance ?instance__) (name record-waiting-threads) (value ?record-waiting-threads)))
    (assert (modeler-instance-param (instance ?instance__) (name needs-kernel-callstack) (value ?needs-kernel-callstack)))
    (assert (modeler-instance-param (instance ?instance__) (name target) (value ?target)))
    (assert (modeler-instance-param (instance ?instance__) (name high-freq) (value ?high-freq)))
    (bind-output-table ?t1__)
    (bind-input-table time-sample (attribute target $?target) (attribute sample-rate-micro-seconds 100) (attribute callstack (if (eq (nth$ 1 ?needs-kernel-callstack) 1) then (create$ user kernel) else (create$ user))))
    (assert (modeler-instance-param (instance ?instance__) (name record-waiting-threads) (value ?record-waiting-threads)))
    (assert (modeler-instance-param (instance ?instance__) (name needs-kernel-callstack) (value ?needs-kernel-callstack)))
    (assert (modeler-instance-param (instance ?instance__) (name target) (value ?target)))
    (assert (modeler-instance-param (instance ?instance__) (name high-freq) (value ?high-freq)))
)
(defrule binding-rule-3
    (declare (salience 101))
    (unbound-table-instance (table-id ?t1__) (has schema time-profile))
    (unbound-table-instance (table-id ?t1__) (has record-waiting-threads $?record-waiting-threads))
    (unbound-table-instance (table-id ?t1__) (has record-waiting-threads 0))
    (unbound-table-instance (table-id ?t1__) (has target-pid $?target))
    (unbound-table-instance (table-id ?t1__) (has high-frequency-sampling $?high-freq))
    (unbound-table-instance (table-id ?t1__) (has high-frequency-sampling 1))
    (unbound-table-instance (table-id ?t1__) (has needs-kernel-callstack $?needs-kernel-callstack))
    =>
    (bind ?instance__ (create-modeler-instance))
    (assert (modeler-instance (instance ?instance__) (from-rule-number 3)))
    (bind-output-table ?t1__)
    (bind-input-table time-sample (attribute target $?target) (attribute sample-rate-micro-seconds 100) (attribute callstack (if (eq (nth$ 1 ?needs-kernel-callstack) 1) then (create$ user kernel) else (create$ user))))
    (assert (modeler-instance-param (instance ?instance__) (name record-waiting-threads) (value ?record-waiting-threads)))
    (assert (modeler-instance-param (instance ?instance__) (name needs-kernel-callstack) (value ?needs-kernel-callstack)))
    (assert (modeler-instance-param (instance ?instance__) (name target) (value ?target)))
    (assert (modeler-instance-param (instance ?instance__) (name high-freq) (value ?high-freq)))
)
(defrule binding-rule-4
    (declare (salience 300))
    (unbound-table-instance (table-id ?t0__) (has schema time-profile))
    (unbound-table-instance (table-id ?t0__) (has record-waiting-threads $?record-waiting-threads))
    (unbound-table-instance (table-id ?t0__) (has record-waiting-threads 1))
    (unbound-table-instance (table-id ?t0__) (has target-pid $?target))
    (unbound-table-instance (table-id ?t0__) (has high-frequency-sampling $?high-freq))
    (unbound-table-instance (table-id ?t0__) (has high-frequency-sampling 1))
    (unbound-table-instance (table-id ?t0__) (has needs-kernel-callstack $?needs-kernel-callstack))
    (unbound-table-instance (table-id ?t1__&~?t0__) (has schema time-profile))
    (unbound-table-instance (table-id ?t1__) (has record-waiting-threads $?record-waiting-threads))
    (unbound-table-instance (table-id ?t1__) (has record-waiting-threads 0))
    (unbound-table-instance (table-id ?t1__) (has target-pid $?target))
    (unbound-table-instance (table-id ?t1__) (has high-frequency-sampling $?high-freq))
    (unbound-table-instance (table-id ?t1__) (has high-frequency-sampling 1))
    (unbound-table-instance (table-id ?t1__) (has needs-kernel-callstack $?needs-kernel-callstack))
    (unbound-table-instance (table-id ?t2__&~?t0__&~?t1__) (has schema time-profile))
    (unbound-table-instance (table-id ?t2__) (has needs-kernel-callstack $?needs-kernel-callstack))
    (unbound-table-instance (table-id ?t2__) (has record-waiting-threads $?record-waiting-threads))
    (unbound-table-instance (table-id ?t2__) (has target-pid $?target))
    =>
    (bind ?instance__ (create-modeler-instance))
    (assert (modeler-instance (instance ?instance__) (from-rule-number 4)))
    (bind-output-table ?t0__)
    (bind-input-table time-sample (attribute sample-rate-micro-seconds 1000) (attribute all-thread-states YES) (attribute callstack (if (eq (nth$ 1 ?needs-kernel-callstack) 1) then (create$ user kernel) else (create$ user))) (attribute target $?target))
    (assert (modeler-instance-param (instance ?instance__) (name record-waiting-threads) (value ?record-waiting-threads)))
    (assert (modeler-instance-param (instance ?instance__) (name needs-kernel-callstack) (value ?needs-kernel-callstack)))
    (assert (modeler-instance-param (instance ?instance__) (name target) (value ?target)))
    (assert (modeler-instance-param (instance ?instance__) (name high-freq) (value ?high-freq)))
    (bind-output-table ?t1__)
    (bind-input-table time-sample (attribute target $?target) (attribute sample-rate-micro-seconds 100) (attribute callstack (if (eq (nth$ 1 ?needs-kernel-callstack) 1) then (create$ user kernel) else (create$ user))))
    (assert (modeler-instance-param (instance ?instance__) (name record-waiting-threads) (value ?record-waiting-threads)))
    (assert (modeler-instance-param (instance ?instance__) (name needs-kernel-callstack) (value ?needs-kernel-callstack)))
    (assert (modeler-instance-param (instance ?instance__) (name target) (value ?target)))
    (assert (modeler-instance-param (instance ?instance__) (name high-freq) (value ?high-freq)))
    (bind-output-table ?t2__)
    (bind-input-table time-sample (attribute sample-rate-micro-seconds 1000) (attribute callstack (if (eq (nth$ 1 ?needs-kernel-callstack) 1) then (create$ user kernel) else (create$ user))) (attribute target $?target) (attribute all-thread-states (if (eq (nth$ 1 ?record-waiting-threads) 1) then YES else NO)))
    (assert (modeler-instance-param (instance ?instance__) (name target) (value ?target)))
    (assert (modeler-instance-param (instance ?instance__) (name needs-kernel-callstack) (value ?needs-kernel-callstack)))
    (assert (modeler-instance-param (instance ?instance__) (name record-waiting-threads) (value ?record-waiting-threads)))
)
(defrule binding-rule-5
    (declare (salience 200))
    (unbound-table-instance (table-id ?t1__) (has schema time-profile))
    (unbound-table-instance (table-id ?t1__) (has record-waiting-threads $?record-waiting-threads))
    (unbound-table-instance (table-id ?t1__) (has record-waiting-threads 0))
    (unbound-table-instance (table-id ?t1__) (has target-pid $?target))
    (unbound-table-instance (table-id ?t1__) (has high-frequency-sampling $?high-freq))
    (unbound-table-instance (table-id ?t1__) (has high-frequency-sampling 1))
    (unbound-table-instance (table-id ?t1__) (has needs-kernel-callstack $?needs-kernel-callstack))
    (unbound-table-instance (table-id ?t2__&~?t1__) (has schema time-profile))
    (unbound-table-instance (table-id ?t2__) (has needs-kernel-callstack $?needs-kernel-callstack))
    (unbound-table-instance (table-id ?t2__) (has record-waiting-threads $?record-waiting-threads))
    (unbound-table-instance (table-id ?t2__) (has target-pid $?target))
    =>
    (bind ?instance__ (create-modeler-instance))
    (assert (modeler-instance (instance ?instance__) (from-rule-number 5)))
    (bind-output-table ?t1__)
    (bind-input-table time-sample (attribute target $?target) (attribute sample-rate-micro-seconds 100) (attribute callstack (if (eq (nth$ 1 ?needs-kernel-callstack) 1) then (create$ user kernel) else (create$ user))))
    (assert (modeler-instance-param (instance ?instance__) (name record-waiting-threads) (value ?record-waiting-threads)))
    (assert (modeler-instance-param (instance ?instance__) (name needs-kernel-callstack) (value ?needs-kernel-callstack)))
    (assert (modeler-instance-param (instance ?instance__) (name target) (value ?target)))
    (assert (modeler-instance-param (instance ?instance__) (name high-freq) (value ?high-freq)))
    (bind-output-table ?t2__)
    (bind-input-table time-sample (attribute sample-rate-micro-seconds 1000) (attribute callstack (if (eq (nth$ 1 ?needs-kernel-callstack) 1) then (create$ user kernel) else (create$ user))) (attribute target $?target) (attribute all-thread-states (if (eq (nth$ 1 ?record-waiting-threads) 1) then YES else NO)))
    (assert (modeler-instance-param (instance ?instance__) (name target) (value ?target)))
    (assert (modeler-instance-param (instance ?instance__) (name needs-kernel-callstack) (value ?needs-kernel-callstack)))
    (assert (modeler-instance-param (instance ?instance__) (name record-waiting-threads) (value ?record-waiting-threads)))
)
(defrule binding-rule-6
    (declare (salience 100))
    (unbound-table-instance (table-id ?t2__) (has schema time-profile))
    (unbound-table-instance (table-id ?t2__) (has needs-kernel-callstack $?needs-kernel-callstack))
    (unbound-table-instance (table-id ?t2__) (has record-waiting-threads $?record-waiting-threads))
    (unbound-table-instance (table-id ?t2__) (has target-pid $?target))
    =>
    (bind ?instance__ (create-modeler-instance))
    (assert (modeler-instance (instance ?instance__) (from-rule-number 6)))
    (bind-output-table ?t2__)
    (bind-input-table time-sample (attribute sample-rate-micro-seconds 1000) (attribute callstack (if (eq (nth$ 1 ?needs-kernel-callstack) 1) then (create$ user kernel) else (create$ user))) (attribute target $?target) (attribute all-thread-states (if (eq (nth$ 1 ?record-waiting-threads) 1) then YES else NO)))
    (assert (modeler-instance-param (instance ?instance__) (name target) (value ?target)))
    (assert (modeler-instance-param (instance ?instance__) (name needs-kernel-callstack) (value ?needs-kernel-callstack)))
    (assert (modeler-instance-param (instance ?instance__) (name record-waiting-threads) (value ?record-waiting-threads)))
)
